﻿using System;
using System.Collections.Generic;
using System.Linq;

using System.Web;
using System.Web.Mvc;
using Gueei.Gallery.Core.Entities;
using Gueei.Gallery.Core.Repositories;
using Gueei.Gallery.Web.Exceptions;
using Gueei.Gallery.Web.RequestModels;
using Gueei.Gallery.Web.ViewModels;

namespace Gueei.Gallery.Web.Controllers
{
    public class BrowseController : Controller
    {
    	private readonly IImageRepository _imageRepo;
    	private readonly ITagRepository _tagRepo;
    	private readonly IAlbumRepository _albumRepo;

		public BrowseController(IImageRepository imageRepo, ITagRepository tagRepo, IAlbumRepository albumRepo)
		{
			_albumRepo = albumRepo;
			_imageRepo = imageRepo;
			_tagRepo = tagRepo;
		}

		[OutputCache(Duration=5,VaryByParam="*")]
		public ActionResult Index(LatestQueryModel query)
		{
			var result = _imageRepo.GetImages();

			var model = new ImageListViewModel();
			FillImageListViewModel(model, query, 
				result.OrderByDescending(i=>i.CreateDate)
					.Skip(query.StartItem-1)
					.Take(query.ItemsPerPage).ToList(), 
				result.Count());
			return View(model);
		}

    	private void FillImageListViewModel(ImageListViewModel model, PagingQueryModelBase query, IList<Image> result, int totalItem)
    	{
    		model.Paging = new PagingViewModel()
    		             	{
    		             		StartItem = query.StartItem,
    		             		ItemsPerPage = query.ItemsPerPage,
    		             		TotalItem = totalItem,
    		             	};

    		model.AddRange(result.Select(ImageViewModel.CreateFromImage));
    	}

    	// Get: /Browse/Latest
		// This will return all the image items in reverse chronological order
		public ActionResult Latest(LatestQueryModel query)
		{
			var result = _imageRepo.GetImages().Skip(query.StartItem).Take(query.ItemsPerPage);
			// Assume all output in JSON format
			return View(new {query = query, result = result});
		}

		[ChildActionOnly]
		public ActionResult TagCloud()
		{
			var model = new TagListViewModel();
			model.AddRange(_tagRepo
				.GetTags()
				.OrderByDescending(t=>t.ItemCount)
				.Take(50)
				.ToList()
				.Select(TagViewModel.CreateFromTag));
			return PartialView(model);
		}

		[OutputCache(Duration = 5, VaryByParam = "*")]
		public ActionResult Tags()
		{
			var result = _tagRepo.GetTags().ToList();
			return View(result.Select(t=>new { name = t.Name, count= t.ItemCount}));
		}

		[OutputCache(Duration = 5, VaryByParam = "*")]
		public ActionResult Tag(TagBrowseImageRequestModel query)
		{
			var tag = _tagRepo.GetTag(query.Name, false);
			if (tag == null)
				throw new ResourceNotFoundException("Tag: " + query.Name + " is undefined.");
			var model = new TagImageListViewModel();
			var images = _imageRepo.GetImages().Where(i => i.Tags.Contains(tag));
			model.TagName = query.Name;
			FillImageListViewModel(model, query, 
				images
				.Skip(query.StartItem)
				.Take(query.ItemsPerPage)
				.ToList(), images.Count());
			return View(model); 
		}

		public ActionResult Album(AlbumViewRequestModel query)
		{
			var album = _albumRepo.GetAlbumById(query.Id);
			if (album == null)
				throw new ResourceNotFoundException("Album: " + query.Id + " is not available.");
			var model = new AlbumImageListViewModel {
				AlbumName = album.Name,
				Tags = album.Tags.Select(t=> t.Name).ToArray()
			};
			FillImageListViewModel(model, query, 
				album.Images.Skip(query.StartItem).Take(query.ItemsPerPage).ToList(),
				album.Images.Count);

			return View(model);
		}

		public ActionResult Albums(PagingQueryModelBase query)
		{
			var result = _albumRepo.GetAllAlbums()
				.Select(a => AlbumViewModel.CreateFromAlbum(a)).ToList();
			var model = new AlbumListViewModel();

			model.Paging = new PagingViewModel() {
				StartItem = query.StartItem,
				ItemsPerPage = query.ItemsPerPage,
				TotalItem = result.Count,
			};

			model.AddRange(result);
			return View(model);
		}
    }
}